﻿Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
Imports System.Net.NetworkInformation
Imports System.IO
Imports System.Data.SqlClient

Public Class frm_host

    Public WithEvents myChat As New TCPChat
    Private myAdapterName, myPhysicalAddress, myGateway, myDNS, strHostName As String
    Private addr() As IPAddress
    Private pool As List(Of message2Send)
    Private isOnline(10) As Boolean
    Private ping(10) As Boolean
    Private isCheckingOnline As Boolean ' = true: asked and waiting for response, = false: already receive response

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        If myChat.isConnected Then myChat.disconnect()
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load


        '//Read HostSetting.ini
        Dim fR As StreamReader = New StreamReader(SETTING_FILE)
        Dim i As Integer
        Dim st As String

        nShops = fR.ReadLine().Replace(" ", "").Replace("nShops=", "")
        For i = 0 To nShops - 1
            st = fR.ReadLine
            Shops(i) = st.Split("|")(0)
            ShopsIP(i) = st.Split("|")(1)
            ShopsPort(i) = st.Split("|")(2)
        Next

        If nShops > 0 Then
            lbl_ip1.Text = Shops(0) & "'s IP"
            tbx_remoteIP1.Text = ShopsIP(0)
            tbx_remotePort1.Text = ShopsPort(0)
        End If
        If nShops > 1 Then
            lbl_ip2.Text = Shops(1) & "'s IP"
            tbx_remoteIP2.Text = ShopsIP(1)
            tbx_remotePort2.Text = ShopsPort(1)
        End If
        If nShops > 2 Then
            lbl_ip3.Text = Shops(2) & "'s IP"
            tbx_remoteIP3.Text = ShopsIP(2)
            tbx_remotePort3.Text = ShopsPort(2)
        End If
        If nShops > 3 Then
            lbl_ip4.Text = Shops(3) & "'s IP"
            tbx_remoteIP4.Text = ShopsIP(3)
            tbx_remotePort4.Text = ShopsPort(3)
        End If
        If nShops > 4 Then
            lbl_ip5.Text = Shops(4) & "'s IP"
            tbx_remoteIP5.Text = ShopsIP(4)
            tbx_remotePort5.Text = ShopsPort(4)
        End If

        nRetries = fR.ReadLine().Replace(" ", "").Replace("nRetries=", "")
        RetryEverySec = fR.ReadLine().Replace(" ", "").Replace("RetryEverySec=", "")
        CheckConnEveryMin = fR.ReadLine().Replace(" ", "").Replace("CheckConnEveryMin=", "")

        fR.Close()


        '//init today target
        LoadTarget()

        ''//init isOnline
        For i = 0 To nShops - 1
            isOnline(i) = False
            ping(i) = 0
        Next

        '// Getting Ip address of local machine.
        '// First get the host name of local machine.
        strHostName = Dns.GetHostName()
        Dim ipEntry As IPHostEntry = Dns.GetHostEntry(strHostName)
        addr = ipEntry.AddressList
        For i = 0 To addr.Length - 1

            If addr(i).AddressFamily = AddressFamily.InterNetwork Then
                StatusLabel_adapter.Text = "host " & strHostName & _
                                           String.Format(" IP: {0}", addr(i).ToString)
                Exit For
            End If
        Next

        tbx_remoteIP1.Text = ShopsIP(0)
        tbx_remotePort1.Text = ShopsPort(0)
        tbx_hostIP.Text = addr(i).ToString
        tbx_hostPort.Text = "5000"
        'tbx_remoteIP.Text = addr(i).ToString

        pool = New List(Of message2Send)

        '//load time
        Timer_clock.Interval = 10 * 1000
        Timer_clock.Enabled = True
        Timer_clock.Start()

        lbl_hour.Text = Format(Now, "dd/MM/yyyy HH:mm")
        lbl_hour.Left = (Me.Width - lbl_hour.Width) / 2

    End Sub

    Private Sub LoadTarget()
        Using connection As New SqlConnection(ConnectionString)
            connection.Open()

            Dim sql = "SELECT * FROM schedule WHERE DateId='" & Today & "'"

            Dim cmd As New SqlCommand(sql, connection)
            cmd.CommandType = CommandType.Text

            Dim shopCode As String
            Dim plan As String
            Dim models() As String
            Dim target, i As Integer

            Dim reader As SqlDataReader = cmd.ExecuteReader()
            While (reader.Read())
                target = 0

                shopCode = reader.GetString(1)
                plan = reader.GetString(2)
                models = plan.Split("|")

                For i = 0 To models.Length - 1
                    target += models(i).Split(":")(1)
                Next

                Select Case shopCode
                    Case "BDY" : lbl_bdy_target.Text = target
                    Case "CHA" : lbl_cha_target.Text = target
                    Case "PNT" : lbl_pnt_target.Text = target
                    Case "FNG" : lbl_fin_target.Text = target
                    Case "TRI" : lbl_tri_target.Text = target
                End Select
            End While
            reader.Close()
            cmd.Dispose()
        End Using
    End Sub

    Private Sub btn_Connect_Click(sender As Object, e As EventArgs) Handles btn_Connect.Click
        myChat.connect(tbx_hostIP.Text, CInt(tbx_hostPort.Text))
        If myChat.isConnected Then
            CurrentTask = TASK_ASK_ONL
            isCheckingOnline = False
            Timer_online.Interval = CheckConnEveryMin * 60 * 1000
            Timer_online.Enabled = True
            Timer_online.Start()
            Timer_online_Tick(Timer_online, e)

            '//start the pooling
            Timer_sendMsg.Interval = RetryEverySec * 1000
            Timer_sendMsg.Enabled = True
            Timer_sendMsg.Start()
        End If
    End Sub

    Private Sub btn_Disconnect_Click(sender As Object, e As EventArgs) Handles btn_Disconnect.Click
        myChat.disconnect()
    End Sub

    Private Sub btn_clear_Click(sender As Object, e As EventArgs) Handles btn_clear.Click
        lbout.Items.Clear()
    End Sub

    Private Sub connection(ByVal status As Boolean) Handles myChat.connection
        btn_Connect.Enabled = Not status
        btn_Disconnect.Enabled = status
        'tbx_remoteIP1.Enabled = Not status
        'tbx_remotePort1.Enabled = Not status
        'tbx_hostIP.Enabled = Not status
        'tbx_hostPort.Enabled = Not status
        tbin.Enabled = status

        If status Then
            StatusLabel_adapter.Image = My.Resources.ledCornerGreen
            StatusLabel_receive.Image = My.Resources.ledCornerOrange
        Else
            StatusLabel_adapter.Image = My.Resources.ledCornerGray
            StatusLabel_receive.Image = My.Resources.ledCornerGray
            StatusLabel_send.Image = My.Resources.ledCornerGray
        End If
    End Sub

    Private Sub myChat_Datareceived(txt As String) Handles myChat.Datareceived
        lbout.Items.Add(Now & " >>In >> " & txt)

        Dim i As Integer = 0
        Dim idx As Integer = 0
        Dim shopCode As String = txt.Substring(0, 3)
        If (shopCode <> "BDY") AndAlso (shopCode <> "CHA") AndAlso _
            (shopCode <> "FNG") AndAlso (shopCode <> "PNT") AndAlso (shopCode <> "TRI") Then
            Exit Sub
        End If

        While (shopCode <> Shops(idx)) AndAlso (idx < nShops)
            idx += 1
        End While

        If txt.Contains("PROD") Then
            'ShopCode|PROD|Plan|Actual
            Select Case shopCode
                Case "BDY"
                    pic_bdy.Image = My.Resources.green
                    lbl_bdy_plan.Text = txt.Split("|")(2)
                    lbl_bdy_actual.Text = txt.Split("|")(3)
                    lbl_bdy_diff.Text = CInt(lbl_bdy_actual.Text) - CInt(lbl_bdy_plan.Text)
                    If (CInt(lbl_bdy_diff.Text) < 0) Then
                        lbl_bdy_diff.ForeColor = Color.Red
                    Else
                        lbl_bdy_diff.ForeColor = Color.Blue
                    End If

                Case "CHA"
                    pic_cha.Image = My.Resources.green
                    lbl_cha_plan.Text = txt.Split("|")(2)
                    lbl_cha_actual.Text = txt.Split("|")(3)
                    lbl_cha_diff.Text = CInt(lbl_cha_actual.Text) - CInt(lbl_cha_plan.Text)
                    If (CInt(lbl_cha_diff.Text) < 0) Then
                        lbl_cha_diff.ForeColor = Color.Red
                    Else
                        lbl_cha_diff.ForeColor = Color.Blue
                    End If

                Case "PNT"
                    pic_pnt.Image = My.Resources.green
                    lbl_pnt_plan.Text = txt.Split("|")(2)
                    lbl_pnt_actual.Text = txt.Split("|")(3)
                    lbl_pnt_diff.Text = CInt(lbl_pnt_actual.Text) - CInt(lbl_pnt_plan.Text)
                    If (CInt(lbl_pnt_diff.Text) < 0) Then
                        lbl_pnt_diff.ForeColor = Color.Red
                    Else
                        lbl_pnt_diff.ForeColor = Color.Blue
                    End If

                Case "FNG"
                    pic_fin.Image = My.Resources.green
                    lbl_fin_plan.Text = txt.Split("|")(2)
                    lbl_fin_actual.Text = txt.Split("|")(3)
                    lbl_fin_diff.Text = CInt(lbl_fin_actual.Text) - CInt(lbl_fin_plan.Text)
                    If (CInt(lbl_fin_diff.Text) < 0) Then
                        lbl_fin_diff.ForeColor = Color.Red
                    Else
                        lbl_fin_diff.ForeColor = Color.Blue
                    End If

                Case "TRI"
                    pic_trim.Image = My.Resources.green
                    lbl_tri_plan.Text = txt.Split("|")(2)
                    lbl_tri_actual.Text = txt.Split("|")(3)
                    lbl_tri_diff.Text = CInt(lbl_tri_actual.Text) - CInt(lbl_tri_plan.Text)
                    If (CInt(lbl_tri_diff.Text) < 0) Then
                        lbl_tri_diff.ForeColor = Color.Red
                    Else
                        lbl_tri_diff.ForeColor = Color.Blue
                    End If
            End Select

            For i = 0 To nShops - 1
                If shopCode = Shops(i) Then
                    ping(i) = False 'already receive signal from this shop
                    Exit For
                End If
            Next

            'send the ack
            If idx < nShops Then
                myChat.SendData("OK", ShopsIP(idx), ShopsPort(idx))
                txtOutSend("OK")
            End If


        ElseIf txt.Contains("WORK") Then
            'client reply ack for Working Schedule
            For i = pool.Count - 1 To 0 Step -1
                If (shopCode = pool(i).code) AndAlso (pool(i).msg.StartsWith("WORK")) Then
                    pool.RemoveAt(i)
                End If
            Next

        ElseIf txt.Contains("ONLN") Then
            'client reply ack for ONL status
            Select Case shopCode
                Case "BDY"
                    pic_bdy.Image = My.Resources.green

                Case "CHA"
                    pic_cha.Image = My.Resources.green

                Case "PNT"
                    pic_pnt.Image = My.Resources.green

                Case "FNG"
                    pic_fin.Image = My.Resources.green

                Case "TRI"
                    pic_trim.Image = My.Resources.green
            End Select

        ElseIf txt.Contains("SCHE") Then
            'clinet reply for receiving schedule

        ElseIf txt.Contains("ASKS") Then
            'clinet reply with the schedule

        End If

        Dim StillHaveThings2Send As Boolean = False

        For i = 0 To pool.Count - 1
            If pool(i).nRetries < nRetries Then
                StillHaveThings2Send = True
            End If
        Next

        'if nothing else in the pool, then resume the checkOnline
        If Not StillHaveThings2Send Then
            Timer_online.Enabled = True
            Timer_online.Start()
        End If

    End Sub

    Private Sub rdata(ByVal receiveStatus As Boolean) Handles myChat.recOK
        If receiveStatus Then
            StatusLabel_receive.Image = My.Resources.ledCornerGreen
            'StatusLabel_adapter.Text = "local " & myChat.Local.ToString & _
            '                           " remote" & myChat.Remote.ToString

        Else
            StatusLabel_receive.Image = My.Resources.ledCornerRed
        End If
    End Sub

    Private Sub sendata(ByVal sendStatus As Boolean) Handles myChat.sendOK
        If sendStatus Then
            StatusLabel_send.Image = My.Resources.ledCornerGreen
        Else
            StatusLabel_send.Image = My.Resources.ledCornerRed
        End If
    End Sub

    Private Sub tbinKD(ByVal sender As Object, _
                       ByVal e As KeyEventArgs) Handles tbin.KeyDown
        If e.KeyCode = Keys.Enter Then
            With CType(sender, TextBox)
                If .Text.Length > 0 Then
                    StatusLabel_send.Image = My.Resources.ledCornerGray
                    myChat.SendData(.Text, tbx_remoteIP1.Text, CInt(tbx_remotePort1.Text))
                    txtOutSend(.Text)
                    .Text = String.Empty
                End If
            End With
        End If
    End Sub

    Private Sub txtOutSend(ByVal txt As String)
        lbout.Items.Add(Now & " <<Out<< " & txt)
        lbout.TopIndex = lbout.Items.Count - 1
    End Sub

    Private Sub Timer_Clock_Tick(sender As Object, e As EventArgs) Handles Timer_clock.Tick
        lbl_hour.Text = Format(Now, "dd/MM/yyyy   HH:mm")
        lbl_hour.Left = (Me.Width - lbl_hour.Width) / 2
    End Sub

    Private Sub btn_working_Click(sender As Object, e As EventArgs) Handles btn_working.Click
        NeedToUpdateWorkHour = False
        frm_workHour.ShowDialog()
        If NeedToUpdateWorkHour Then
            For i = 0 To nShops - 1
                If isOnline(i) Then
                    pool.Add(New message2Send(WorkingHourString, Shops(i), ShopsIP(i), ShopsPort(i)))
                    'UpdateWorkingHour(WorkingHourString, ShopsIP(i), ShopsPort(i))
                End If
            Next
            Timer_sendMsg_Tick(Timer_sendMsg, e)
        End If
    End Sub

    Private Sub btn_duration_Click(sender As Object, e As EventArgs) Handles btn_duration.Click
        frm_Duration.ShowDialog()
    End Sub

    Private Sub btn_sched_Click(sender As Object, e As EventArgs) Handles btn_sched.Click
        frm_schedule.ShowDialog()
    End Sub

    Private Sub btn_stat_Click(sender As Object, e As EventArgs) Handles btn_stat.Click

    End Sub


    '============================
    '=====COMMUNICATION PART=====
    '============================
    Private Sub Timer_sendMsg_Tick(sender As Object, e As EventArgs) Handles Timer_sendMsg.Tick
        Dim i As Integer = 0
        'Dim msg As String
        'Select Case CurrentTask
        '    Case TASK_WORK
        '    Case TASK_SCHE
        '    Case TASK_ASK_SCHE
        '    Case TASK_ASK_ONL
        '        msg = "ONLN"
        '        myChat.SendData(msg, ShopsIP(i), ShopsPort(i))
        '        txtOutSend(msg)
        'End Select

        'check all the pool to see any msg need to send???
        For i = 0 To pool.Count - 1
            If pool(i).nRetries < nRetries Then
                'if anything need to send then stop the online checking function
                Timer_online.Enabled = False
                Timer_online.Stop()

                pool(i).nRetries += 1
                myChat.SendData(pool(i).msg, pool(i).toIP, pool(i).toPort)
                txtOutSend(pool(i).msg)
                Thread.Sleep(500)
            End If
        Next
    End Sub

    'Public Sub UpdateWorkingHour(content As String, toShopIP As String, toShopPort As Integer)
    '    CurrentTask = TASK_WORK
    '    'Timer2.Interval = nRetries
    '    'Timer2.Enabled = True
    '    'Timer2.Start()
    '    'Timer2_Tick(Timer2, New EventArgs)
    '    myChat.SendData(content, toShopIP, toShopPort)
    'End Sub

    Private Sub Timer_online_Tick(sender As Object, e As EventArgs) Handles Timer_online.Tick
        Dim i As Integer = 0
        Dim msg As String

        If isCheckingOnline Then 'asked, after 15sec, check again if received responsed?
            For i = 0 To nShops - 1
                If ping(i) = True Then
                    Select Case Shops(i)
                        Case "BDY" : pic_bdy.Image = My.Resources.red
                        Case "CHA" : pic_cha.Image = My.Resources.red
                        Case "PNT" : pic_pnt.Image = My.Resources.red
                        Case "FNG" : pic_fin.Image = My.Resources.red
                        Case "TRI" : pic_trim.Image = My.Resources.red
                    End Select
                End If
            Next

            Timer_online.Interval = CheckConnEveryMin * 60000
            isCheckingOnline = False
        Else
            For i = 0 To nShops - 1
                msg = "PROD" 'ask for PROD instead of ONLN, if client respons then online
                myChat.SendData(msg, ShopsIP(i), ShopsPort(i))
                txtOutSend(msg)
                ping(i) = True
                Thread.Sleep(500)
            Next

            isCheckingOnline = True
            Timer_online.Interval = RetryEverySec * 1000
        End If
        
    End Sub

End Class
